package com.fanrui.code.player;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.beanutils.BeanUtils;
import com.fanrui.code.dao.FamilyListDao;
import com.fanrui.code.db.jvmdb.IPersistable;
import com.fanrui.code.entity.FamilyList;
import com.fanrui.code.entity.User;
import com.fanrui.code.family.FamilyDao;
import com.fanrui.code.family.FamilyEntity;
import com.fanrui.code.family.FamilyMember;
import com.fanrui.code.util.logger.Stdout;
import com.fanrui.proto.cmd.CurrencyType;
import com.fanrui.proto.cmd.PlayerInfoCmd;
import com.fanrui.proto.cmd.PlayerSimpleInfoCmd;

/**
 * 主要用于操作那些不在线的玩家IScoreRank
 * @author Administrator
 *
 */
public class Player implements IPersistable<Long>, Comparable<Player> {

	 // ======================== player基本对象 ===========================//
	
	 /**
     * 编号
     */
    private Long id;

    /**
     * 账号
     */
    private String account;

    /**
     * 密码
     */
    private String password;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 头像
     */
    private String headUrl;

    /**
     * 连续签到天数
     */
    private Integer continuousSignDay;
    /**
     * 连续签到时间
     */
    private String continuousSignTime;
    /**
    * 最新签到时间
    */
   private String continuousSignLastTime;
   
   private String ip;

   private double x;
   
   private double y;

    public String getContinuousSignLastTime() {
		return continuousSignLastTime;
	}

	public void setContinuousSignLastTime(String continuousSignLastTime) {
		this.continuousSignLastTime = continuousSignLastTime;
	}
	/**
     * 性别
     */
    private String sex;
    
	/**
	 * 家族
	 */
	private volatile FamilyEntity familyData = null;
	
	/**
	 * 俱乐部
	 */
	private Map<Integer,FamilyEntity> clubList = Collections.emptyMap();
	
	private FamilyEntity beginClub = null;
	
	private Integer family;
    // ======================== 需要转换的对象 ===========================//
	
	/**
	 * 金币
	 */
	protected AtomicLong gold;

	/**
	 * 砖石
	 */
	protected AtomicLong money;

	/**
	 * 玩家所在牌桌
	 */
	private Integer gamerId = null;
	
	
	private String invitationCode;

	public String getInvitationCode() {
		return invitationCode;
	}

	public void setInvitationCode(String invitationCode) {
		this.invitationCode = invitationCode;
	}

	/**
	 * 身份证认证
	 */
//	private VerifiedCmd verified = null;

	//===================================== 构造方法 ====================================//
	
	public Player() {}
	
	public Player(User user) {
		load(user);
	}
	
	public FamilyEntity getFamilyData() {
		return familyData;
	}
	
	public int getFamilyId() {
		if (familyData != null) {
			return familyData.getId();
		} else {
			return -1;
		}
	}
	public void setFamilyData(FamilyEntity family) {
		if(family == null) {
			this.familyData = null;
			return;
		}
		synchronized (family) {
			this.familyData = family;
		}
	}

	//===================================== 初始化方法 ====================================//
	
	public void load(User user) {
		try {
			BeanUtils.copyProperties(this, user);
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
		// 金币
		if(user.getGold() == null) {
			gold = new AtomicLong(0);
		}else {
			gold = new AtomicLong(user.getGold());
		}
		// 钻石
		if(user.getMoney() == null) {
			money = new AtomicLong(0);
		}else {
			money = new AtomicLong(user.getMoney());
		}
		// 性别
		sex = user.getSex();
	}
	
	/**
	 * 保存玩家信息
	 */
	public void save() {
		PlayerDao.getInstance().save(this);
	}
	
	//===================================== 登录 ====================================//
	
//	public void login() {
//		Integer todyLoginCount = LoginInfoDao.getInstance().selectTodayLoginNum(DateUtil.getDateToString(DateUtil.getZeroTime()), getId());
//		if (todyLoginCount == 1) { // 今日首次登录
//			refreDayData();
//		}
//	}

	/**
	 * 刷新每日数据
	 */
//	private void refreDayData() {
//		PlayerData playerData = PlayerData.createPlayerData(this);
//		// 给VIP玩家补偿金币
//		if(getCurrencyValue(CurrencyType.C_Gold) < getVipSupplyNum() && getCurrencyValue(CurrencyType.C_VIP) >= 1) {
//			operationCost(CurrencyType.C_Gold, getVipSupplyNum(), OperationType.Set);
//			PlayerLogUtil.log(this, PlayerOpertionType.VipSupply, getVipSupplyNum(), null, null, null, null, "vip每日补给", null, playerData);
//			// 发送通知
//			NotifyGetSupplyGold.Builder notify = NotifyGetSupplyGold.newBuilder();
//			notify.setType(NotifyGetSupplyGold.SupplyType.VIPSupply);
//			notify.setGold(getVipSupplyNum());
//			PlayerSessions.sendPlayerMsg(getId(), notify.build());
//		}
//		// 重置补偿金币次数
//		operationCost(CurrencyType.C_DaySupplyNum,
//				ParameterConfigManager.getInstance().getIntParameter(EParameterType.DaySupplyNum), OperationType.Set);
//		// 重置轮盘次数
//		operationCost(CurrencyType.C_Roulette, 1, OperationType.Set);
//		save();
//	}
	
	
	
	//===================================== SET/GET ====================================//

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getHeadUrl() {
		return headUrl;
	}

	public void setHeadUrl(String headUrl) {
		this.headUrl = headUrl;
	}
	
	public String getSex() {
		return sex;
	}

	public Integer getContinuousSignDay() {
		return continuousSignDay;
	}

	public void setContinuousSignDay(Integer continuousSignDay) {
		this.continuousSignDay = continuousSignDay;
	}

	public String getContinuousSignTime() {
		return continuousSignTime;
	}

	public void setContinuousSignTime(String continuousSignTime) {
		this.continuousSignTime = continuousSignTime;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public long getGold() {
		return gold.get();
	}

	public long getMoney() {
		return money.get();
	}

	public Integer getGamerId() {
		return gamerId;
	}

	public void setGamerId(Integer gamerId) {
		this.gamerId = gamerId;
	}

	public void setId(Long id) {
		this.id = id;
	}
	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public Long getId() {
		return id;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
	}

	@Override
	public void setPersistKey(Long id) {
		this.id = id;
	}

	@Override
	public Long getPersistKey() {
		return id;
	}

	//================================== 货币相关 ============================================//
	
	public enum CostOperationResult {
		/**
		 * 操作失败
		 */
		OperationFail,
		/**
		 * 操作成功
		 */
		OperationSuccess;

	}
	
	/**
	 * 操作类型
	 */
	public enum OperationType {
		Set, Minus, Add;
	}
	
	/**
	 * 只允许通过此方法修改 玩家的货币值
	 */
	public CostOperationResult operationCost(CurrencyType costType, Long costValue, OperationType operationType) {
		if (costValue == null) {
			return CostOperationResult.OperationSuccess;
		}
		final int cost = Math.abs(costValue.intValue());
		// 减操作要保证操作的同步
		if (OperationType.Minus == operationType) {
			if (costValue == 0) {
				return CostOperationResult.OperationSuccess;
			}
			synchronized (this) {
				if (getCurrencyValue(costType) >= cost) {
					minusCurrencyValue(costType, cost);
				} else {
					return CostOperationResult.OperationFail;
				}
			}
		} else if (OperationType.Add == operationType) {
			if (costValue == 0) {
				return CostOperationResult.OperationSuccess;
			}
			addCurrencyValue(costType, cost);
		} else if (OperationType.Set == operationType) {
			setCurrencyValue(costType, costValue.intValue());
		}
		save();
		return CostOperationResult.OperationSuccess;
	}
	
	/**
	 * 获取某种货币值
	 */
	public long getCurrencyValue(CurrencyType currencyType) {
		if (currencyType == CurrencyType.C_Gold) {
			return getGold();
		}
		if (currencyType == CurrencyType.C_Money) {
			return getMoney();
		}
		return 0l;
	}

	/**
	 * 增加某种货币的值，确保intValue为正数
	 * @param costType 货币类型（金币，钻石）
	 * @param intValue 操作的数量
	 */
	private void addCurrencyValue(CurrencyType costType, int cost) {
		if(costType == CurrencyType.C_Gold) {
			gold.addAndGet(cost);
		}
		if(costType == CurrencyType.C_Money) {
			money.addAndGet(cost);
		}
	}
	
	/**
	 * 减少
	 * @param operationType
	 * @param costType
	 * @param cost
	 */
	private void minusCurrencyValue(CurrencyType costType, int cost) {
		if(costType == CurrencyType.C_Gold) {
			gold.addAndGet(-cost);
		}
		if(costType == CurrencyType.C_Money) {
			money.addAndGet(-cost);
		}
	}
	
	/**
	 * 设置
	 * @param costType
	 * @param intValue
	 */
	private void setCurrencyValue(CurrencyType costType, int cost) {
		if(costType == CurrencyType.C_Gold) {
			gold.set(cost);
		}
		if(costType == CurrencyType.C_Money) {
			money.set(cost);
		}
	}
	
	public User toUser() {
		User user = new User();
		try {
			BeanUtils.copyProperties(user, this);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		user.setGold(getGold());
		user.setMoney(getMoney());
		return user;
	}

	public PlayerInfoCmd toCmd() {
		PlayerInfoCmd.Builder builder = PlayerInfoCmd.newBuilder();
		builder.setAccount(account);
		builder.setGold(getGold());
		builder.setNickname(nickname);
		builder.setMoney(getMoney());
		builder.setPlayerId(getId());
		builder.setHeadIconUrl(getHeadUrl());
		builder.setInvitationCode(getInvitationCode());
		return builder.build();
	}

	public boolean isGobanging() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int compareTo(Player o) {
		// TODO Auto-generated method stub
		return 0;
	}

	//=============================================== 物品相关 ==========================================//
	
//	/**
//	 * 添加物品
//	 * @param itemBag
//	 */
//	public void addItem(ItemBag itemBag) {
//		if(itemBag == null || itemBag.getNum() == 0) {
//			return;
//		}
//		for (int i = 0; i < itemBag.getNum(); i++) {
//			addItem(itemBag.getConfig());
//		}
//	}
//	
//	/**
//	 * 添加一个物品
//	 * @param item
//	 */
//	public void addItem(Item item) {
//		if (item == null) {
//			Stdout.GET().info("玩家{}添加物品失败 物品为空", getId());
//			return;
//		}
//		// 查看背包是否有该种物品，没有就添加，有了就修改物品数量
//		int itemId = item.getId();
//		ItemBag itemBag = getItemToBag(itemId); 
//		if(itemBag == null) {
//			itemBag = new ItemBag();
//			itemBag.setConfig(item);
//			itemBag.setItemId(itemId);
//			itemBag.addNum();
//			ItemBag old = itemBags.put(itemId, itemBag);
//			if (null != old) {// 再次检查物品是否已经存在
//				itemBag.addNum(old.getNum());
//			}
//		}else {
//			itemBag.addNum();
//		}
//		Stdout.GET().info("玩家{}添加物品{}成功 ,当前拥有此物品数量{}", getId(), itemId, getItemNum(itemId));
//		if (item.getImmediatelyUes() != null && item.getImmediatelyUes()) {
//			useItem(item.getId());
//		}
//		
//	}
//	
//	/**
//	 * 使用物品
//	 * @param itemId
//	 */
//	public ResUseItem.Result useItem(int itemId) {
//		// TODO 使用物品
//		
//		return ResUseItem.Result.Success;
//	}
//
//	/**
//	 * 根据物品id，从背包中获取一个物品
//	 * @param itemId
//	 * @return
//	 */
//	public synchronized ItemBag getItemToBag(int itemId) {
//		if (itemBags != null) {
//			return itemBags.get(itemId);
//		} else {
//			return null;
//		}
//	}
//	
//	/**
//	 * 获取一个物品的数量
//	 */
//	public int getItemNum(int itemId) {
//		ItemBag itemBag = getItemToBag(itemId);
//		if (itemBag != null) {
//			return itemBag.getNum();
//		} else {
//			return 0;
//		}
//	}
	/**
	 * 从俱乐部列表中移除
	 * */
	public synchronized void removeToClubList(FamilyEntity rclub){
		if(clubList == null || !clubList.containsKey(rclub.getId())){
			return;
		}
		clubList.remove(rclub.getId());
		
		// 重新加载初始俱乐部
		if(beginClub != null) {
			if(rclub.getId() == beginClub.getId()) {
				if(clubList != null && !clubList.isEmpty()) {
					for(FamilyEntity club : clubList.values()) {
						if(beginClub == null && club.getMembers().containsKey(this.getId())) {
							beginClub = club;
							continue;
						}
						if(family != null && club.getMembers().containsKey(this.getId())) {
							FamilyMember old = beginClub.getMembers().get(this.getId());
							FamilyMember news = club.getMembers().get(this.getId());
							if(old != null && news != null) {
								if(news.getJoinTime() < old.getJoinTime()) {
									beginClub = club;
								}
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 添加俱乐部到俱乐部列表
	 * */
	public synchronized  void addClubToList(FamilyEntity club){
//		for(Integer clubId:clubList.keySet()){
//			if(clubId == club.getId()){
//				return;
//			}
//		}
//		if(clubList == null || !clubList.containsKey(club.getId())){
//			return;
//		}
		if(clubList == null || clubList.isEmpty()) {
			clubList = new HashMap<>();
		}
		clubList.put(club.getId(), club);
		save();
	}
	
	/**
	 * 是否已经加入了该俱乐部
	 * @param club
	 * @return 存在返回true
	 */
	public boolean checkHavaClub(Integer clubId) {
		if(!clubList.isEmpty() && clubId != null) {
			for(Integer id : clubList.keySet()) {
				if(id.equals(clubId)){
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * 根据俱乐部Id查询玩家俱乐部
	 * @param clubId
	 * @return
	 */
	public FamilyEntity getClubById(Integer clubId) {
		if(!clubList.isEmpty() && clubId != null) {
			for(FamilyEntity club : clubList.values()) {
				if(club != null && club.getId() == clubId.intValue()) {
					return club;
				}
			}
		}
		return null;
	}
	
	/**
	 * 转换为命令对象
	 */
	public PlayerSimpleInfoCmd toSimpleCmd() {
		PlayerSimpleInfoCmd.Builder builder = PlayerSimpleInfoCmd.newBuilder();
		builder.setGold(getGold());
		builder.setId(getId());
		builder.setMoney(getMoney());
		builder.setNickName(getNickname());
		return builder.build();
	}
	public void loadFamily() {
		if (family != null && family != -1) {
			FamilyEntity entity = FamilyDao.getInstance().findById(family);
			if (entity != null) {
				setFamilyData(entity);
			}
		}
	}
	public void loadClubs() {
		// 玩家加入的俱乐部
		clubList = new HashMap<Integer, FamilyEntity>();
		List<FamilyList> clubs = FamilyListDao.getInstance().queryPlayersClub(id);
		if(clubs != null && !clubs.isEmpty()) {
//			JsonArray clubListJson = new JsonParser().parse(allClubs).getAsJsonArray(); 
//			if(clubListJson != null && clubListJson.size() > 0){
//				for (final JsonElement element : clubListJson) {
//					Integer clubId = (int) element.getAsLong();
//					FamilyEntity club = FamilyDao.getInstance().findById((int)clubId);
//					if(club != null){
//						clubList.put(clubId, club);
//					}else{
//						Stdout.GET().info("玩家{}加载家族{}出现错误，未能加载！！！",getId(),clubId);
//					}
//				}
//			}
			for(FamilyList f : clubs) {
				FamilyEntity club = FamilyDao.getInstance().findById((int)f.getClubId());
				if(club != null){
					clubList.put(f.getClubId(), club);
				}else{
					Stdout.GET().info("玩家{}加载家族{}出现错误，未能加载！！！",getId(),f.getClubId());
				}
			}
		}
		
		// 加载玩家最开始加入的俱乐部
		if(clubList != null && !clubList.isEmpty()) {
			for(FamilyEntity club : clubList.values()) {
				if(beginClub == null && club.getMembers().containsKey(this.getId())) {
					beginClub = club;
					continue;
				}
				if(family != null && club.getMembers().containsKey(this.getId())) {
					FamilyMember old = beginClub.getMembers().get(this.getId());
					FamilyMember news = club.getMembers().get(this.getId());
					if(old != null && news != null) {
						if(news.getJoinTime() < old.getJoinTime()) {
							beginClub = club;
						}
					}
				}
			}
		}
	}
}
